package org.ttitfly.workflow.engine.persistence.hibernate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springside.modules.orm.hibernate.HibernateDao;
import org.ttitfly.ttcore.util.HibernateDateUtil;
import org.ttitfly.workflow.engine.AbstractRunUnit;
import org.ttitfly.workflow.engine.run.Task;

/**
 * 
 * @author panhaichun
 *
 */
@Component
public class HibernateTaskDao extends HibernateDao<Task, Integer> {
	
	/**
	 * 按条件统计任务数量
	 * @param principal 操作人身份标识
	 * @param processName 流程名称，精确匹配
	 * @param activityName 活动名称，模糊匹配
	 * @param processInstanceName 流程实例名称，全模糊匹配
	 * @param status 任务状态
	 * @return
	 */
	public int count(String principal, String processName, String activityName, int processInstanceId, int[] status) {
		List<Object> params = new ArrayList<Object>();
		StringBuilder hql = new StringBuilder(" SELECT COUNT(*) FROM ");
		hql.append(Task.class.getName()).append(" WHERE 1 = 1 ");
		if (activityName != null && !"".equals(activityName = activityName.trim())) {
			hql.append(" AND unitName LIKE ? ");
			params.add("%" + activityName + "%");
		}
		/*
		if (processName != null && !"".equals(processName = processName.trim())) {
			hql.append(" AND processInstance.processName = ? ");
			params.add(processName);
		}
		if (processInstanceName != null && !"".equals(processInstanceName = processInstanceName.trim())) {
			hql.append(" AND processInstance.name LIKE ? ");
			params.add("%" + processInstanceName + "%");
		}
		*/
		if (processInstanceId > 0) {
			hql.append(" AND processInstance.id = ? ");
			params.add(processInstanceId);
		}
		
		if (status != null && status.length > 0) {
			hql.append(" AND status IN ( ");
			for (int s : status) {
				hql.append("?,");
				params.add(s);
			}
			hql.deleteCharAt(hql.length() - 1);
			hql.append(" ) ");
		}
		if (principal != null && !"".equals(principal = principal.trim())) {
			//hql.append(" AND ( assigners LIKE ? OR assigners IS NULL OR assigners = '' ) ");
			hql.append(" AND assigners LIKE ? ");
			params.add("%" + principal + "%");
		}
		Query query = getSession().createQuery(hql.toString());
		int i = 0;
		for (Object param : params) {
			query.setParameter(i++, param);
		}
		Number count = (Number) query.uniqueResult();
		return count.intValue();
	}
	
	/**
	 * 按条件分页查询任务
	 * @param principal 操作人身份标识
	 * @param processName 流程名称，精确匹配
	 * @param activityName 活动名称，模糊匹配
	 * @param processInstanceName 流程实例名称，全模糊匹配
	 * @param status 任务状态
	 * @param start 开始下标，从0开始
	 * @param count 查询的数量，如果小于等于0认为是查询所有
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Task> find(String principal, String processName, String activityName, int processInstanceId, int[] status, int start, int count) {
		List<Object> params = new ArrayList<Object>();
		StringBuilder hql = new StringBuilder(" FROM ");
		hql.append(Task.class.getName()).append(" WHERE 1 = 1 ");
		if (activityName != null && !"".equals(activityName = activityName.trim())) {
			hql.append(" AND unitName = ? ");
			params.add(activityName);
		}
	/*
		if (processName != null && !"".equals(processName = processName.trim())) {
			hql.append(" AND processInstance.processName = ? ");
			params.add(processName);
		}
		if (processInstanceName != null && !"".equals(processInstanceName = processInstanceName.trim())) {
			hql.append(" AND processInstance.name LIKE ? ");
			params.add("%" + processInstanceName + "%");
		}
	*/
		if (processInstanceId > 0) {
			hql.append(" AND processInstance.id = ? ");
			params.add(processInstanceId);
		}
		
		if (status != null && status.length > 0) {
			hql.append(" AND status IN ( ");
			for (int s : status) {
				hql.append("?,");
				params.add(s);
			}
			hql.deleteCharAt(hql.length() - 1);
			hql.append(" ) ");
		}
		if (principal != null && !"".equals(principal = principal.trim())) {
			//hql.append(" AND ( assigners = ? OR assigners IS NULL OR assigners = '' ) ");
			//hql.append(" AND assigners = ? ");
			//params.add(principal);
			hql.append(" AND assigners LIKE ? ");
			params.add("%" + principal + "%");
		}
		hql.append(" ORDER BY id DESC ");
		Query query = getSession().createQuery(hql.toString());
		if (start >= 0) {
			query.setFirstResult(start);
		}
		if (count > 0) {
			//query.setFetchSize(count);
			query.setMaxResults(count);
		}
		int i = 0;
		for (Object param : params) {
			query.setParameter(i++, param);
		}
		return query.list();
	}
	
	public List<Task> findClosedTask(int processInstanceId) {
		String hql = " FROM " + Task.class.getName() + " t WHERE t.processInstance.id = ? AND t.status = ? ";
		return this.find(hql, processInstanceId, AbstractRunUnit.CLOSED);
	}


	public List<Task> findRunningTask(int processInstanceId) {
		String hql = " FROM " + Task.class.getName() + " t WHERE t.processInstance.id = ? AND t.status = ? ";
		return this.find(hql, processInstanceId, AbstractRunUnit.RUNNING);
	}

	public boolean removeTask(int processInstanceId){
		StringBuilder hql = new StringBuilder("delete from wf_task where process_instance_id = ?");
		Query q =  getSession().createSQLQuery(hql.toString());
		q.setInteger(0, processInstanceId);
		 //执行更新语句
		int num =q.executeUpdate();  
		if(num >0){
			return true;
		}else{
			return false;
		}
	}
	
	public boolean removeProcessInstance(int processInstanceId){
		StringBuilder hql = new StringBuilder("delete from wf_process_instance where id = ?");
		Query q =  getSession().createSQLQuery(hql.toString());
		q.setInteger(0, processInstanceId);
		 //执行更新语句
		int num =q.executeUpdate();  
		if(num >0){
			return true;
		}else{
			return false;
		}
	}

	@SuppressWarnings("unchecked")
	public List<Task> findTaskByClosedTime(String closedTime){
		List<Task> taskList = new ArrayList<Task>();
		Date[] dateArrsy = HibernateDateUtil.hibernateDateHelper(closedTime);
		Criteria criteria = this.getSession().createCriteria(Task.class.getName());
		criteria.add(Restrictions.eq("unitName","开工批复"));
		criteria.add(Restrictions.eq("status",3));
		criteria.add(Restrictions.between("closeTime", dateArrsy[0], dateArrsy[1]));
		List list = criteria.list();
		if(list != null && list.size() > 0){
			taskList = list;
		}
		return taskList;
	}
	
}
